/*
    BibleNotebook - A bible reader software
    Copyright (C) 2014  Williams Fernando Lopez

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
 */

/*
 * Selector.java
 *
 * Created on 2/07/2013, 03:09:48 PM
 */

package com.simplebible.ui.components;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.ListSelectionModel;
import com.simplebible.bible.BibleUtils;
import wl.util.TextResourcesUtil;
import wl.util.Utils;
import com.simplebible.bible.objects.Abreviation;
import com.simplebible.bible.objects.Bible;
import com.simplebible.bible.objects.Book;
import com.simplebible.bible.objects.Chapter;
import com.simplebible.objects.Preferences;
import com.simplebible.bible.objects.SearchResult;
import com.simplebible.bible.objects.Verse;
import com.simplebible.util.HumanVerseParser;

/**
 *
 * @author Williams Lopez
 */
public class Selector extends javax.swing.JPanel {

    Bible bible;
    Book bookSelected;
    Chapter chapterSelected;
    private JPopupMenu popupSelector = new JPopupMenu();
    private ActionListener selectListener;
    private ActionListener searchEndListener;
    NotificationPane notifPane = new NotificationPane();
    Abreviation verseEnteredInTextField = null;

    /** Creates new form Selector */
    public Selector() {
        initComponents();
        this.jList2.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        this.jList2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        this.jList1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        this.jList2.setFixedCellHeight(25);
        this.jList2.setFixedCellWidth(35);
        this.setSize(400, 350);
        popupSelector.add(this);
        notifPane.setLocation(jList2, 0, 0);
        notifPane.setSize(jList2.getSize());
        try {
            TextResourcesUtil.registrarComponente(this);
        } catch (Exception e) {
        }

    }

    public void setBible(Bible bible){
        this.bible = bible;
        this.jList1.removeAll();
        DefaultListModel listModel = new DefaultListModel();
        for(int i=0;i<bible.getBooks().size();i++){
            Book book = bible.getBooks().get(i);
            listModel.addElement(book);
        }
        this.jList1.setModel(listModel);
        this.jList1.setSelectedIndex(0);

    }

    public void setSelected(Book book, Chapter cap){
        this.bookSelected = book;
        this.chapterSelected = cap;

        jList1.setSelectedValue(this.bookSelected, true);
        jList2.setSelectedValue(this.chapterSelected.getOrden()+1, true);

    }

    public void show(Component invoquer, int x, int y){
        this.jTextField1.requestFocus();
        popupSelector.show(invoquer, x, y);
        this.jTextField1.requestFocus();
    }

    public ActionListener getSelectListener() {
        return selectListener;
    }

    public void setSelectListener(ActionListener selectListener) {
        this.selectListener = selectListener;
    }

    public ActionListener getSearchEndListener() {
        return searchEndListener;
    }

    public void setSearchEndListener(ActionListener searchEndListener) {
        this.searchEndListener = searchEndListener;
    }





    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jList1 = new javax.swing.JList();
        jTextField1 = new javax.swing.JTextField();
        jScrollPane2 = new javax.swing.JScrollPane();
        jList2 = new javax.swing.JList();
        buttonBuscar = new wl.ui.ButtonLabel();

        setBackground(new java.awt.Color(255, 255, 255));

        jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
        jScrollPane1.setBorder(javax.swing.BorderFactory.createTitledBorder(""));

        jList1.setBackground(new java.awt.Color(250, 253, 255));
        jList1.setFont(new java.awt.Font("Tahoma", 0, 16));
        jList1.setForeground(new java.awt.Color(102, 102, 102));
        jList1.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jList1ValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(jList1);

        jTextField1.setFont(new java.awt.Font("Tahoma", 1, 12));
        jTextField1.setForeground(new java.awt.Color(102, 102, 102));
        jTextField1.setBorder(javax.swing.BorderFactory.createTitledBorder(""));
        jTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jTextField1KeyReleased(evt);
            }
        });

        jScrollPane2.setBorder(null);

        jList2.setBackground(new java.awt.Color(250, 253, 255));
        jList2.setBorder(javax.swing.BorderFactory.createTitledBorder(""));
        jList2.setFont(new java.awt.Font("Tahoma", 0, 16)); // NOI18N
        jList2.setForeground(new java.awt.Color(102, 102, 102));
        jList2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jList2MouseClicked(evt);
            }
        });
        jList2.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jList2ValueChanged(evt);
            }
        });
        jScrollPane2.setViewportView(jList2);

        buttonBuscar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simplebible/ui/img/1372999232_book_search.png"))); // NOI18N
        buttonBuscar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonBuscarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 238, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 202, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonBuscar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(buttonBuscar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 258, Short.MAX_VALUE)))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jList1ValueChanged
        setCapitulos((Book)this.jList1.getSelectedValue());
    }//GEN-LAST:event_jList1ValueChanged

    private void jTextField1KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextField1KeyReleased
        filtrar();
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            if (verseEnteredInTextField != null) {
                seleccionar(verseEnteredInTextField);
            } else {
                buscarEnTexto();
            }
        }
    }//GEN-LAST:event_jTextField1KeyReleased

    private void jList2ValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jList2ValueChanged
        
    }//GEN-LAST:event_jList2ValueChanged

    private void jList2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jList2MouseClicked
        seleccionar();
    }//GEN-LAST:event_jList2MouseClicked

    private void buttonBuscarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonBuscarActionPerformed
        if(verseEnteredInTextField!=null){
            seleccionar(verseEnteredInTextField);
        }else{
            buscarEnTexto();
        }
    }//GEN-LAST:event_buttonBuscarActionPerformed


    public void buscarEnTexto(){

        if(!this.buttonBuscar.isEnabled()){
            return;
        }

        final String texto = jTextField1.getText().trim();
        notifPane.show("Buscando "+texto+" ....", "Buscando "+texto+" ....", NotificationPane.TYPE_WAITING);

        if (texto.equals("")) {
            return;
        }


        Thread t = new Thread (){

            @Override
            public void run() {

                buttonBuscar.setEnabled(false);

                try {
                    List<SearchResult> res = BibleUtils.foundInBible(bible, texto);

                    if (searchEndListener != null) {
                        searchEndListener.actionPerformed(new ActionEvent(res, 0, texto));
                    }
                    
                } catch (Exception e) {
                    Utils.printToLog("Error al realizar la busqueda", e, Preferences.LOG_LEVEL_ERROR);
                }
                notifPane.setVisible(false);
                buttonBuscar.setEnabled(true);
                setVisible(false);
            }
        };
        t.start();



    }


    public void seleccionar(){
        Book book = (Book)this.jList1.getSelectedValue();
        if(book == null){
            return;
        }
        Integer cap = (Integer)this.jList2.getSelectedValue();
        if(cap==null){
            return;
        }
        Abreviation abr = book.getAbreviation().cloneChanging(Abreviation.FIELD_CHAPTER, cap.toString());
        abr.setVerse("1");

        seleccionar(abr);

    }

    public void seleccionar(Abreviation abr){
        ActionEvent ae = new ActionEvent(abr, 0, "selectChapter");
        getSelectListener().actionPerformed(ae);
        setVisible(false);
    }

    public void filtrar(){
        String text = this.jTextField1.getText().trim().toLowerCase();
        DefaultListModel dlm2 = new DefaultListModel();


        //Abreviation humanData = BibleUtils.getHumanDataFromText(text);
        Abreviation humanData;
        
        try {
            humanData = HumanVerseParser.parse(text);
        } catch (Exception e) {
            return;
        }

        if(humanData.getChapter() != null){
            text = humanData.getBook();
        }

        for(int i=0;i<bible.getBooks().size();i++){
            Book b = (Book)bible.getBooks().get(i);
            if(text.equals("") || !Utils.searchInText(b.getHumanName().toLowerCase(), text, false, false, true).isEmpty()){
                dlm2.addElement(b);
            }
        }
        this.jList1.setModel(dlm2);

        if(dlm2.getSize()>0){
           this.jList1.setSelectedIndex(0);

            try {

                Chapter ch = null;
                Verse   ve = null;

                if (humanData.getChapter() != null) {
                    ch = BibleUtils.findChapter((Book) this.jList1.getSelectedValue(), humanData.getChapter());
                }

                if(humanData.getVerse() != null && ch !=null){
                    ve = BibleUtils.findVerse(ch,humanData.getVerse());
                }

                if(ve != null){
                    verseEnteredInTextField = ve.getAbreviation();
                }else if(ch != null){
                    verseEnteredInTextField = ch.getAbreviation().cloneChanging(Abreviation.FIELD_VERSE, "1");
                }else{
                    verseEnteredInTextField = null;
                }

                if(verseEnteredInTextField!=null){
                    this.jList2.setSelectedValue(Integer.parseInt(verseEnteredInTextField.getChapter()), true);
                }

            } catch (Exception e) {
                Utils.printToLog("No se pudo encontrar el versiculo: " + humanData, e, Preferences.LOG_LEVEL_ERROR);
            }
        }
    }

    @Override
    public void setVisible(boolean aFlag) {
        if(aFlag){
            this.jTextField1.requestFocus();
            verseEnteredInTextField = null;
        }
        this.popupSelector.setVisible(false);
        //super.setVisible(aFlag);
    }


    public void setCapitulos(Book book){

        if(book == null){
            return;
        }

        int caps = book.getChapters().size();


        this.jList2.removeAll();
        DefaultListModel model = new DefaultListModel();


        for(int i=1;i<=caps;i++){
            model.addElement(i);
        }
        this.jList2.setModel(model);

    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private wl.ui.ButtonLabel buttonBuscar;
    private javax.swing.JList jList1;
    private javax.swing.JList jList2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTextField jTextField1;
    // End of variables declaration//GEN-END:variables

}
